/**
 * WebSocket核心基类
 * 包含重连、心跳、消息队列等通用逻辑
 * 具体平台的连接方法由子类实现
 */
export class WebSocketCore {
  /**
   * 构造函数
   * @param {string} url WebSocket服务器地址
   * @param {Object} [options] 配置选项
   * @param {number} [options.reconnectMax=5] 最大重连次数
   * @param {number} [options.heartBeatInterval=30000] 心跳间隔(ms)
   * @param {number} [options.reconnectDelay=5000] 重连延迟(ms)
   */
  constructor(url, options = {}) {
    // 配置参数
    this.url = url;
    this.reconnectMax = options.reconnectMax || 5;
    this.heartBeatInterval = options.heartBeatInterval || 30000;
    this.reconnectDelay = options.reconnectDelay || 5000;
    
    // 内部状态
    this.reconnectCount = 0;
    this.reconnectTimer = null;
    this.heartBeatTimer = null;
    this.messageQueue = [];
    this.isConnected = false;
    
    // 事件监听器
    this.messageListeners = [];
    this.openListeners = [];
    this.closeListeners = [];
    this.errorListeners = [];
  }
  
  /**
   * 连接WebSocket服务器（由子类实现）
   */
  _connect() {
    throw new Error('_connect方法必须由子类实现');
  }
  
  /**
   * 发送原始消息（由子类实现）
   * @param {string} message 原始消息字符串
   */
  _sendRaw(message) {
    throw new Error('_sendRaw方法必须由子类实现');
  }
  
  /**
   * 关闭原始连接（由子类实现）
   * @param {number} [code] 关闭代码
   */
  _closeRaw(code) {
    throw new Error('_closeRaw方法必须由子类实现');
  }
  
  /**
   * 平台相关连接成功处理
   */
  _handlePlatformOpen() {
    this._handleOpen();
  }
  
  /**
   * 平台相关消息处理
   * @param {string|Object} data 消息数据
   */
  _handlePlatformMessage(data) {
    this._handleMessage(data);
  }
  
  /**
   * 平台相关错误处理
   * @param {Error} error 错误对象
   */
  _handlePlatformError(error) {
    this._handleError(error);
  }
  
  /**
   * 平台相关关闭处理
   * @param {Object} event 关闭事件对象
   */
  _handlePlatformClose(event) {
    this._handleClose(event);
  }
  
  /**
   * 公共连接方法
   */
  connect() {
    this._connect();
  }
  
  /**
   * 公共发送方法
   * @param {Object|string} data 要发送的数据
   */
  send(data) {
    const message = typeof data === 'string' ? data : JSON.stringify(data);
    
    if (!this.isConnected) {
      // 连接未建立，存入消息队列
      this.messageQueue.push(message);
      return;
    }
    
    try {
      this._sendRaw(message);
    } catch (e) {
      console.error('[WebSocket] Send exception:', e);
      this.messageQueue.push(message);
    }
  }
  
  /**
   * 公共关闭方法
   * @param {number} [code=1000] 关闭代码
   */
  close(code = 1000) {
    this._stopReconnect();
    this._stopHeartBeat();
    this._closeRaw(code);
    this.isConnected = false;
  }
  
  /**
   * 添加消息监听器
   * @param {Function} listener 消息监听函数
   */
  onMessage(listener) {
    this.messageListeners.push(listener);
  }
  
  /**
   * 添加连接打开监听器
   * @param {Function} listener 连接打开监听函数
   */
  onOpen(listener) {
    this.openListeners.push(listener);
  }
  
  /**
   * 添加连接关闭监听器
   * @param {Function} listener 连接关闭监听函数
   */
  onClose(listener) {
    this.closeListeners.push(listener);
  }
  
  /**
   * 添加错误监听器
   * @param {Function} listener 错误监听函数
   */
  onError(listener) {
    this.errorListeners.push(listener);
  }
  
  /**
   * 移除所有监听器
   */
  removeAllListeners() {
    this.messageListeners = [];
    this.openListeners = [];
    this.closeListeners = [];
    this.errorListeners = [];
  }
  
  // ==================== 内部方法 ====================
  
  /**
   * 处理连接打开事件
   */
  _handleOpen() {
    console.log('[WebSocket] Connected');
    this.isConnected = true;
    this.reconnectCount = 0;
    this._triggerOpen();
    this._startHeartBeat();
    this._flushMessageQueue();
  }
  
  /**
   * 处理消息事件
   * @param {string} data 原始消息数据
   */
  _handleMessage(data) {
    try {
      // 尝试解析JSON数据
      const parsed = JSON.parse(data);
      this._triggerMessage(parsed);
    } catch (e) {
      // 解析失败则直接传递原始数据
      this._triggerMessage(data);
    }
  }
  
  /**
   * 处理错误事件
   * @param {Object} error 错误对象
   */
  _handleError(error) {
    console.error('[WebSocket] Error:', error);
    this._triggerError();
    this._reconnect();
  }
  
  /**
   * 处理连接关闭事件
   * @param {Object} event 关闭事件对象
   */
  _handleClose(event) {
    console.log('[WebSocket] Closed:', event);
    this.isConnected = false;
    this._triggerClose();
    this._stopHeartBeat();
    
    // 非主动关闭时重连
    if (event.code !== 1000) {
      this._reconnect();
    }
  }
  
  /**
   * 重新连接
   */
  _reconnect() {
    this._stopReconnect();
    
    if (this.reconnectCount >= this.reconnectMax) {
      console.error(`[WebSocket] Reconnect failed after ${this.reconnectMax} attempts`);
      return;
    }
    
    this.reconnectTimer = setTimeout(() => {
      console.log(`[WebSocket] Reconnecting... (${this.reconnectCount + 1}/${this.reconnectMax})`);
      this.reconnectCount++;
      this.close();
      this.connect();
    }, this.reconnectDelay);
  }
  
  /**
   * 停止重连
   */
  _stopReconnect() {
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = null;
    }
  }
  
  /**
   * 开始心跳检测
   */
  _startHeartBeat() {
    this._stopHeartBeat();
    this.heartBeatTimer = setInterval(() => {
      if (this.isConnected) {
        this.send({ type: 'heartbeat', timestamp: Date.now() });
      } else {
        this._stopHeartBeat();
      }
    }, this.heartBeatInterval);
  }
  
  /**
   * 停止心跳检测
   */
  _stopHeartBeat() {
    if (this.heartBeatTimer) {
      clearInterval(this.heartBeatTimer);
      this.heartBeatTimer = null;
    }
  }
  
  /**
   * 发送队列中的消息
   */
  _flushMessageQueue() {
    while (this.messageQueue.length > 0) {
      const message = this.messageQueue.shift();
      this._sendRaw(message);
    }
  }
  
  /**
   * 触发消息事件
   * @param {Object|string} data 消息数据
   */
  _triggerMessage(data) {
    this.messageListeners.forEach(listener => listener(data));
  }
  
  /**
   * 触发连接打开事件
   */
  _triggerOpen() {
    this.openListeners.forEach(listener => listener());
  }
  
  /**
   * 触发连接关闭事件
   */
  _triggerClose() {
    this.closeListeners.forEach(listener => listener());
  }
  
  /**
   * 触发错误事件
   */
  _triggerError() {
    this.errorListeners.forEach(listener => listener());
  }
}